﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 事件案例2
{

    //public delegate void GreetingDelegate(string name);

    //public class GreetingManager
    //{
    //    /// <summary>
    //    /// 在 GreetingManager 类的内部声明 delegate1 变量
    //    /// </summary>
    //    public GreetingDelegate delegate1;

    //    public void GreetPeople(string name, GreetingDelegate MakeGreeting)
    //    {
    //        MakeGreeting(name);
    //    }
    //}

    //class Program
    //{
    //    private static void EnglishGreeting(string name)
    //    {
    //        Console.WriteLine("Good Morning, " + name);
    //    }

    //    private static void ChineseGreeting(string name)
    //    {
    //        Console.WriteLine("早上好, " + name);
    //    }


    //    static void Main(string[] args)
    //    {
    //        GreetingManager gm = new GreetingManager();
    //        gm.delegate1 = EnglishGreeting;
    //        gm.delegate1 += ChineseGreeting;
    //        gm.GreetPeople("Liker", gm.delegate1);
    //        //尽管这样做没有任何问题，但我们发现这条语句很奇怪。在调用gm.GreetPeople 方法的时候，再次传递了gm 的delegate1 字段
    //    }

    /*-------------------------------------------------------------------------------------------------------------------------------------------------------
     --------------------------------------------------------------------------------------------------------------------------------------------------------  
            既然如此，我们何不修改 GreetingManager 类成这样：*/

    public delegate void GreetingDelegate(string name);

    public class GreetingManager
    {
        /// <summary>
        /// 在 GreetingManager 类的内部声明 delegate1 变量
        /// </summary>
        public GreetingDelegate delegate1;

        public void GreetPeople(string name)
        {
            if (delegate1 != null) // 如果有方法注册委托变量
            {
                delegate1(name); // 通过委托调用方法
            }
        }
    }
    //public class GreetingManager
    //{
    //    /// <summary>
    //    /// 在 GreetingManager 类的内部声明 delegate1 变量
    //    /// </summary>
    //    public GreetingDelegate delegate1;

    //    public void GreetPeople(string name, GreetingDelegate MakeGreeting)
    //    {
    //        MakeGreeting(name);
    //    }
    //}

    class Program
    {
        private static void EnglishGreeting(string name)
        {
            Console.WriteLine("Good Morning, " + name);
        }

        private static void ChineseGreeting(string name)
        {
            Console.WriteLine("早上好, " + name);
        }


        //static void Main(string[] args)
        //{
        //    GreetingManager gm = new GreetingManager();
        //    gm.delegate1 = EnglishGreeting;
        //    gm.delegate1 += ChineseGreeting;
        //    gm.GreetPeople("Liker", gm.delegate1);
        //    //尽管这样做没有任何问题，但我们发现这条语句很奇怪。在调用gm.GreetPeople 方法的时候，再次传递了gm 的delegate1 字段
        //}

        static void Main(string[] args)
        {
            GreetingManager gm = new GreetingManager();
            gm.delegate1 = EnglishGreeting;
            gm.delegate1 += ChineseGreeting;
            //注意，这次不需要再传递 delegate1 变量
            gm.GreetPeople("Liker");
            //尽管这样达到了我们要的效果，但是还是存在着问题：在这里，delegate1 和我们平时用的string 类型的变量没有什么分别，
            //而我们知道，并不是所有的字段都应该声明成public，合适的做法是应该public 的时候public，应该private 的时候private。
            //我们先看看如果把 delegate1 声明为 private 会怎样？结果就是：这简直就是在搞笑。
            //因为声明委托的目的就是为了把它暴露在类的客户端进行方法的注册，你把它声明为 private 了，客户端对它根本就不可见，那它还有什么用？
            //再看看把delegate1 声明为 public 会怎样？结果就是：在客户端可以对它进行随意的赋值等操作，严重破坏对象的封装性。
            //最后，第一个方法注册用“=”，是赋值语法，因为要进行实例化，第二个方法注册则用的是“+=”。
            //但是，不管是赋值还是注册，都是将方法绑定到委托上，除了调用时先后顺序不同，再没有任何的分别，这样不是让人觉得很别扭么？
            //现在我们想想，如果delegate1 不是一个委托类型，而是一个string 类型，你会怎么做？答案是使用属性对字段进行封装。
        }
    }































}
